home *** CD-ROM | disk | FTP | other *** search
- { $D-} { Debug Information Off }
- {$S-} { Stack Checking Off }
- {$V-} { String Checking Off }
-
- Unit BOIDecl;
- { Part of BBS Onliner Interface }
- { Copyright (C) 1990,1992 Andrew J. Mead
- All Rights Reserved. }
-
- { original version 10/20/90
- history found in IOLIB.PAS }
-
- INTERFACE
-
- Uses
- crt,
- DOS;
-
- Const
- BOI_Version = '1.40'; { BBS Onliner Interface Version Number }
-
- { DOS file sharing attributes, used with OpenFile, OpenText }
- read_only = $00; { ---- -000 open file for read only }
- writeonly = $01; { ---- -001 open file for write only }
- readwrite = $02; { ---- -010 open file for reading and writing }
- denyall = $10; { -001 ---- deny file access to other programs }
- denywrite = $20; { -010 ---- deny write access to other programs }
- denyread = $30; { -011 ---- deny read access to other programs }
- denynone = $40; { -100 ---- allow full access to other programs }
-
- Type
- ptrmask = record { segment:offset mask for address pointers }
- poff : word;
- pseg : word
- end;
-
- timearr = array [1..4] of word; { used in Time/Date functions }
- basearr = array [$0..$F] of byte;
- facctype = (treset,trewrite,tappend); { file access modes }
- tasktype = (notask,dv,dos5,win,os2); { CPU taskers }
-
- boi_grmode = (gr_none,gr_ascii,gr_ansi,gr_avt,gr_tpcrt);
- { graphics modes : none, ASCII, ANSI, AVATAR, CRT }
- boi_commode = (com_none,com_local,com_internal,com_fossil);
- { communication modes : none, local, internal, FOSSIL }
- boi_statmodes = (sm_help1,sm_time,sm_comm,sm_vid);
- { status line display options : }
- { time left, comm settings, remote video mode }
- boi_dropmode = (df_none,df_pcb14x,df_other);
- { drop file types : none, PCBoard 14.x, other }
-
- stdproc = procedure; { procedural variable type }
-
- Const
- boi_r_color : boolean = false; { use color indicator (remote) }
- boi_l_color : boolean = false; { use color indicator (local) }
- boi_local : boolean = true; { local mode indicator }
- boi_echo : boolean = false; { echo info locally indicator }
- boi_quiet : boolean = false; { supress local bell ringing }
- boi_ctsrts : boolean = false; { modem has locked baud rate }
- boi_replay : boolean = false; { allow multiple play }
- boi_checkcd : boolean = true; { use carrier detect routines }
- boi_timeover : boolean = false; { time has expired indicator }
- boi_againtime : word = 10; { time minimum for Again play }
- boi_statmode : boi_statmodes = sm_time; { status line display mode }
- boi_allowavt : boolean = false; { AVATAR allowed indicator }
- dos_share : boolean = true; { DOS SHARE is loaded }
-
- boi_portadd : word = $03F8; { Com1 } { serial port address }
- boi_portnum : word = 0; { Com1 } { serial port number (absolute) }
- boi_portint : word = $0C; { IRQ4 } { serial port interrupt vector }
- boi_picmask : byte = $EF; { IRQ4 } { 8259A port initialization value }
- boi_pic2msk : byte = $00; { if IRQ7..IRQ15 used then this is used }
- boi_cascade : boolean = false; { IRQ7..IRQ15 used indicator }
-
- boi_hoflim : byte = 20; { maximum entries by one player in HOF }
-
- boi_plusidx : byte = 0; { GetCmBBS places ParamStr index value in }
- boi_minusidx : byte = 0; { the given variable. These are the main }
- boi_equalidx : byte = 0; { program definable variables. The program }
- boi_closeidx : byte = 0; { must perform any further processing on }
- boi_openidx : byte = 0; { these switches. }
- boi_dotidx : byte = 0;
-
- boi_portstatus : boolean = false; { internal Async not active }
- boi_cmode : boi_commode = com_none; { remote communications mode }
- boi_cstr : string = ' No Comm'; { status line comm mode string }
- foss_init : byte = $00; { FOSSIL initialization option mask }
-
- boi_dmode : boi_dropmode = df_none; { drop file mode }
- boi_cdlost : boolean = false; { remote dropped carrier indicator }
-
- boi_ticks : longint = $17fe80; { timer ticks left (18.2 per second) }
- boi_stall : longint = 0; { timer ticks since last user activity}
- boi_timer : longint = 0; { timer ticks into the game }
- boi_stime : longint = 0; { time stat line was last updated }
- boi_warntime : word = 5; { next minute to warn user about time at}
-
- boi_ansiarr : basearr = { ANSI colors mapped to text attribute byte }
- (30,34,32,36,31,35,33,37,30,34,32,36,31,35,33,37);
- boi_l_grmode : boi_grmode = gr_tpcrt; { current local graphics mode }
- boi_r_grmode : boi_grmode = gr_ansi; { current remote graphics mode }
-
- boi_nextchar : char = #$00; { used to pass character to IOLib.GetString }
-
- Type
- str39 = string [39];
- charset = set of char;
-
- Var
- boi_pagelength : byte; { size of screen in lines }
- boi_username : str39; { player's name - if available }
- boi_usename : boolean; { availability of users name }
- boi_realname : str39; { player's real name (not alias) - if available }
- boi_usereal : boolean; { availability of real name }
- boi_gametime : integer; { playing time - if available }
- boi_usetime : boolean; { use playing time indicator }
- boi_ticksleft : longint; { time left to play }
- boi_starttime : timearr; { time that game was initialized }
- boi_startdate : timearr; { date that game was initialized }
- boi_extraword : word; { reserved }
- boi_timexp : boolean; { time expired indicator }
- boi_texthof : pathstr; { text hall of fame filename }
-
- boi_gamepath : pathstr; { full DOS path of game's executable }
- boi_gamedir : dirstr; { DOS path of game }
- boi_gamename : namestr; { DOS file name (no extension) of game }
- boi_gameext : extstr; { DOS file name extension of current game }
-
- boi_tasker : tasktype; { Operating System/Environment tasker }
- boi_tvers : word; { version of boi_tasker }
- boi_tstr : string; { string describing boi_tasker }
- boi_tintr : boolean; { Interrupt for tasker functions }
- in_dos : ^boolean; { DOS active indicator }
-
- BOI_Wait : stdproc; { stall procedure / give up time slice }
- BOI_Crit : stdproc; { enter critical region }
- BOI_Safe : stdproc; { exit critical region }
- Procedure BOIInt08h; Interrupt;
-
- IMPLEMENTATION
- {$F+}
- Const
- fossintr = $14; { FOSSIL interrupt }
- dv_intr = $15; { DESQview interrupt }
- dos_intr = $21; { DOS Services interrupt }
- win_intr = $2F; { DOS Multiplexor/Windows interrupt }
-
- lastwait : longint = 0; { static variable indicating last time slice }
- { that was surrendered }
-
- Var
- bd_nextexit : pointer; { pointer to hold address of next Exit procedure }
- oldint08h : pointer; { pointer to hold previous Timer interrupt }
-
- Procedure CALLOLDINT(old : pointer); Far;
- begin {* CallOldInt *}
- Inline($9C/$FF/$5E/$06)
- end; {* CallOldInt *}
-
- Procedure BOIINT08H;
- { chain timer interrupt to handle BOI timing routines }
-
- begin {* iBOIInt08h *}
- if boi_ticks = 0 then boi_timeover := true;
- Dec(boi_ticks); { decrement time remaining }
- Inc(boi_stall); { increment inactivity timer }
- Inc(boi_timer); { increment game timer }
- CallOldInt(oldint08h); { allow CPU to do its thing first }
- Inline($FB) { STI } { allow other interrupts to intercede }
- { additional non-critical processing can go here, in the future
- I plan to write a hook to this section... }
- end; {* iBOIInt08h *}
-
- Procedure NULLPROC; Far;
- begin {* NullProc *}
- end; {* NullProc *}
-
- { DESQview functions }
- Procedure DV_WAIT; Far;
- const
- dvregs : registers = (ax : $1000);
-
- begin {* DV_Wait *}
- if boi_timer - lastwait >= 4 then { only give up one in four time slices }
- begin
- Intr(dv_intr,dvregs);
- lastwait := boi_timer
- end
- end; {* DV_Wait *}
-
- Procedure DV_CRIT; Far;
- const
- dvregs : registers = (ax : $DE1C);
-
- begin {* DV_Crit *}
- Intr(dv_intr,dvregs)
- end; {* DV_Crit *}
-
- Procedure DV_SAFE; Far;
- const
- dvregs : registers = (ax : $101C);
-
- begin {* DV_Safe *}
- Intr(dv_intr,dvregs)
- end; {* DV_Safe *}
-
- Function CHECKDV : boolean; { is DESQview loaded? }
- var
- regs : registers;
-
- begin {* fCheckDV *}
- regs.AX := $2B01;
- regs.CX := $4445; { DE }
- regs.DX := $5351; { SQ }
- Intr($21,regs);
- if regs.AL <> $FF then { set initial values }
- begin
- boi_tasker := dv;
- boi_tvers := regs.BX;
- boi_tintr := true;
- BOI_Wait := DV_Wait;
- BOI_Crit := DV_Crit;
- BOI_Safe := DV_Safe;
- Str(regs.BH + (regs.BL / 100):0:2,boi_tstr);
- boi_tstr := 'DESQview ' + boi_tstr;
- CheckDV := true
- end
- else CheckDV := false
- end; {* fCheckDV *}
-
-
- { MicroSoft Windows functions }
- Procedure MS_WAIT; Far;
- const
- msregs : registers = (ax : $1680);
-
- begin {* MS_Wait *}
- if boi_timer - lastwait >= 4 then { only give up one in four time slices }
- begin
- Intr(win_intr,msregs);
- lastwait := boi_timer
- end
- end; {* MS_Wait *}
-
- Procedure WIN_CRIT; Far;
- const
- winregs : registers = (ax : $1681);
-
- begin {* Win_Crit *}
- Intr(win_intr,winregs)
- end; {* Win_Crit *}
-
- Procedure WIN_SAFE; Far;
- const
- winregs : registers = (ax : $1682);
-
- begin {* Win_Safe *}
- Intr(win_intr,winregs)
- end; {* Win_Safe *}
-
- Function CHECKWINDOZE : boolean; { is MS Windows loaded? }
- var
- regs : registers;
-
- begin {* fCheckWindoze *}
- regs.AX := $1600;
- Intr(win_intr,regs);
- if regs.AL in [$00,$01,$80,$FF] then CheckWindoze := false
- else
- begin { set initial values }
- boi_tasker := win;
- boi_tvers := regs.AL;
- boi_tintr := true;
- BOI_Wait := MS_Wait;
- BOI_Crit := Win_Crit;
- BOI_Safe := Win_Safe;
- Str(regs.AL + (regs.AH / 100):0:2,boi_tstr);
- boi_tstr := 'Windows ' + boi_tstr;
- CheckWindoze := true
- end
- end; {* fCheckWindoze *}
-
- Procedure DOS_IDLE; Far;
- begin {* DOS_Idle *}
- Inline($CD/$28)
- end; {* DOS_Idle *}
-
- Procedure CHECKDOSVERS; { set up DOS/DOS box settings }
- var
- regs : registers;
-
- begin {* CheckDOSVers *}
- boi_tintr := false;
- regs.AX := $3001; { test for DOS version }
- Intr(dos_intr,regs);
- if (regs.AL = $0A) or (regs.AL = $14) then { OS/2 1.x or OS/2 2.x }
- begin { set OS/2 dos box settings }
- boi_tasker := os2;
- if regs.AL = $0A then
- begin
- boi_tvers := 1;
- boi_tstr := 'OS/2 1.x'
- end
- else
- begin
- boi_tvers := 2;
- boi_tstr := 'OS/2 2.x'
- end;
- BOI_Wait := MS_Wait; { works fine }
- BOI_Crit := NullProc; {* Unknown *}
- BOI_Safe := NullProc; {* Unknown *}
- end
- else
- begin { set up DOS settings }
- boi_tvers := regs.AX;
- Str(regs.AL + (regs.AH / 100):0:2,boi_tstr);
- boi_tstr := 'DOS ' + boi_tstr;
- BOI_Crit := NullProc;
- BOI_Safe := NullProc;
- if regs.AL = 5 then { is DOS version 5.0? }
- begin
- boi_tasker := dos5;
- BOI_Wait := MS_Wait
- end
- else
- begin
- boi_tasker := notask;
- BOI_Wait := DOS_Idle
- end
- end
- end; {* fCheckDOSVers *}
-
- Procedure SETINDOS; { set up InDos flag }
- type
- ptrmap = array [0..1] of word;
-
- var
- regs : registers;
- indos : ptrmap absolute in_dos;
-
- begin {* SetInDOS *}
- regs.AH := $34;
- Intr(dos_intr,regs);
- indos[1] := regs.ES;
- indos[0] := regs.BX
- end; {* SetInDOS *}
-
- Procedure BOIEXIT; Far;
- begin {* BOIExit *}
- exitproc := bd_nextexit;
- SetIntVec($08,oldint08h)
- end; {* BOIExit *}
-
- begin {* uBOIDecl *}
- bd_nextexit := exitproc; { install BOIDecl's exit procedure }
- exitproc := @BOIExit;
- GetIntVec($08,oldint08h); { save current timer interrupt }
- SetIntVec($08,@BOIInt08h); { insert BOI timer interrupt }
- GetDate(boi_startdate[1],boi_startdate[2],boi_startdate[3],boi_startdate[4]);
- { set starting date }
- GetTime(boi_starttime[1],boi_starttime[2],boi_starttime[3],boi_starttime[4]);
- { set starting time }
- boi_gamepath := FExpand(ParamStr(0)); { find out who we are! }
- FSplit(boi_gamepath,boi_gamedir,boi_gamename,boi_gameext); { split file }
- SetInDOS; { get indos flag }
-
- { set up CPU tasker stuff }
- if not CheckDV then if not CheckWindoze then CheckDOSVers
- end. {* uBOIDecl *}
-